package com.sciencep.pro.core.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sciencep.pro.common.domain.ResponseResult;
import com.sciencep.pro.core.dao.CalendarInfoMapper;
import com.sciencep.pro.core.domain.dto.calendarinfo.CalendarInfoTO;
import com.sciencep.pro.core.domain.dto.calendarinfo.WeekTo;
import com.sciencep.pro.core.domain.entity.CalendarInfo;
import com.sciencep.pro.core.service.ICalendarInfoService;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

import static java.util.Calendar.DAY_OF_WEEK;

/**
 * @author Sciencep
 */
@Service
public class CalendarInfoServiceImpl extends ServiceImpl<CalendarInfoMapper, CalendarInfo> implements ICalendarInfoService {

    @Override
    public void deleteByYear(Integer year) {
        baseMapper.deleteByYear(year);
    }

    @Override
    public ResponseResult<Object> selectByYear(CalendarInfoTO calendarInfoTO) {
        if (CollUtil.isNotEmpty(this.list(new LambdaQueryWrapper<CalendarInfo>().apply("DATE_FORMAT(date,'%Y')  = " + calendarInfoTO.getYear()).orderByAsc(CalendarInfo::getDate)))
                        && !this.createCalendar(Integer.valueOf(calendarInfoTO.getYear())).getSuccess().equals(true)) {
            return this.createCalendar(Integer.valueOf(calendarInfoTO.getYear()));
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        List<CalendarInfo> calendarInfos = this.list(new LambdaQueryWrapper<CalendarInfo>().apply("DATE_FORMAT(date,'%Y')  = " + calendarInfoTO.getYear()).orderByAsc(CalendarInfo::getDate));
        List<Integer> months = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
        List<List<WeekTo>> list = new ArrayList<>();
        months.forEach(month -> {
            List<WeekTo> holidayWeeks = new ArrayList<>();
            WeekTo holidayWeek = null;
            for (int i = 0; i < calendarInfos.size(); i++) {
                CalendarInfo calendarInfo = calendarInfos.get(i);
                //是否是当天
                if (simpleDateFormat.format(calendarInfo.getDate()).equals(simpleDateFormat.format(new Date()))) {
                    calendarInfo.setIsCurrentDay(true);
                }
                int dayOfMonth = this.getDayOfMonth(calendarInfo.getDate());
                int dayCurrentOfMonth = this.getCurrentDayOfMonth(calendarInfo.getDate());
                if (holidayWeek == null) {
                    holidayWeek = new WeekTo();
                }
                if (month == (calendarInfo.getDate().getMonth() + 1)) {
                    switch (calendarInfo.getWeek()) {
                        case 1:
                            holidayWeek.setMonday(calendarInfo);
                            break;
                        case 2:
                            holidayWeek.setTuesday(calendarInfo);
                            break;
                        case 3:
                            holidayWeek.setWednesday(calendarInfo);
                            break;
                        case 4:
                            holidayWeek.setThursday(calendarInfo);
                            break;
                        case 5:
                            holidayWeek.setFriday(calendarInfo);
                            break;
                        case 6:
                            holidayWeek.setSaturday(calendarInfo);
                            break;
                        case 7:
                            holidayWeek.setSunday(calendarInfo);
                            if (holidayWeek != null) {
                                holidayWeeks.add(holidayWeek);
                            }
                            holidayWeek = null;
                            break;
                        default:
                            break;
                    }
                    if (dayCurrentOfMonth == dayOfMonth) {
                        if (holidayWeek != null) {
                            holidayWeeks.add(holidayWeek);
                        }
                        holidayWeek = null;
                    }
                }
            }
            list.add(holidayWeeks);
        });
        return new ResponseResult<>().success(list);
    }

    @Override
    public ResponseResult<CalendarInfo> saveCalendar(List<CalendarInfoTO> calendarInfoTOList) {
        List<CalendarInfo> calendarInfoList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        for (CalendarInfoTO calendarInfoTO : calendarInfoTOList) {
            CalendarInfo calendarInfo = new CalendarInfo();
            Calendar calendar = Calendar.getInstance();
            if (sdf.format(calendar.getTime()).compareTo(sdf.format(calendarInfoTO.getDate())) <= 0) {
                calendarInfo.setId(calendarInfoTO.getId());
                calendarInfo.setCustomHoliday(calendarInfoTO.getCustomHoliday());
                calendarInfoList.add(calendarInfo);
            }

        }
        if (CollUtil.isNotEmpty(calendarInfoList)) {
            baseMapper.updateCalendarInfoById(calendarInfoList);
            return new ResponseResult<CalendarInfo>().success();
        } else {
            return new ResponseResult<CalendarInfo>().failure("1001", "请设置的节假日");
        }

    }

    //某月的天数
    public int getDayOfMonth(Date date) {
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        aCalendar.setTime(date);
        return aCalendar.getActualMaximum(Calendar.DATE);
    }

    //当前在某月的第几天
    public int getCurrentDayOfMonth(Date date) {
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        aCalendar.setTime(date);
        return aCalendar.get(Calendar.DAY_OF_MONTH);
    }

    @Override
    public ResponseResult<Object> createCalendar(Integer year) {
        List<CalendarInfo> calendarInfoLists = this.list(new LambdaQueryWrapper<CalendarInfo>().last("WHERE DATE_FORMAT(date,'%Y')  = " + year));
        if (CollUtil.isEmpty(calendarInfoLists)) {
            List<CalendarInfo> calendarInfoList = new ArrayList<>();
            Calendar calendar = Calendar.getInstance();
            for (int month = 0; month < 12; month++) {
                calendar.set(Calendar.DATE, 1);
                calendar.set(Calendar.YEAR, year);
                calendar.set(Calendar.MONTH, month);
                int currentMonth = calendar.getActualMaximum(Calendar.DATE);
                for (int date = 1; date <= currentMonth; date++) {
                    calendar.set(year, month, date);
                    CalendarInfo calendarInfo = new CalendarInfo();
                    calendarInfo.setCreateDate(new Date());
                    if (calendar.get(DAY_OF_WEEK) - 1 == 6 || calendar.get(DAY_OF_WEEK) - 1 == 0) {
                        calendarInfo.setDate(calendar.getTime());
                        calendarInfo.setWorkDay(2);
                        calendarInfo.setHoliday(4);
                        calendarInfo.setWeek(calendar.get(DAY_OF_WEEK) - 1 == 0 ? 7 : calendar.get(DAY_OF_WEEK) - 1);
                    } else {
                        calendarInfo.setDate(calendar.getTime());
                        calendarInfo.setWorkDay(1);
                        calendarInfo.setWeek(calendar.get(DAY_OF_WEEK) - 1);
                    }
                    calendarInfoList.add(calendarInfo);
                }
            }
            if (!CollUtil.isEmpty(calendarInfoList)) {
                if (baseMapper.insertCalendarInfos(calendarInfoList) > 0) {
                    return new ResponseResult<Object>().success();
                } else {
                    return new ResponseResult<Object>().failure();
                }
            } else {
                return new ResponseResult<Object>().failure();
            }
        }
        return new ResponseResult<Object>().success();
    }

}
